package com.ctsi.findexpert.service;

import com.ctsi.commons.util.UtilValidate;
import com.ctsi.findexpert.config.HuanXinConfig;
import com.ctsi.findexpert.dto.RegisterResult;
import com.ctsi.findexpert.param.RegisterVO;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Service
@EnableConfigurationProperties(value = HuanXinConfig.class)
public class FindExpertServiceImpl implements FindExpertService {

    private static final Logger logger = LoggerFactory.getLogger(FindExpertServiceImpl.class);

    private Long TOKENTIME = null;

    private Long GRANTTOKENTIME = null;

    private String TOKEN = null;

    @Autowired
    private HuanXinConfig huanXinConfig;

    private RestTemplate restTemplate;

    private RestTemplateBuilder restTemplateBuilder;

    @Autowired
    public FindExpertServiceImpl(RestTemplateBuilder restTemplateBuilder){
        this.restTemplateBuilder = restTemplateBuilder;
        this.restTemplate = restTemplateBuilder.build();
        this.restTemplate.getInterceptors().add((request, body, execution) -> {
            String token = this.getToken();
            request.getHeaders().add("Authorization", "Bearer " + token);
            return execution.execute(request, body);
        });
    }


    @Override
    public String getToken() {
        if (UtilValidate.isNotEmpty(this.TOKEN) && (this.TOKENTIME*1000 - (System.currentTimeMillis() - this.GRANTTOKENTIME) > 60000 )) {
            return this.TOKEN;
        } else {
            MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
            params.add("grant_type","grant_type");
            params.add("client_id",huanXinConfig.getClientId());
            params.add("client_secret",huanXinConfig.getClientSecret());
            ResponseEntity<Map> result = this.restTemplateBuilder.build().postForEntity("http://a1.easemob.com/".concat(huanXinConfig.getOrgName()).concat("/").concat(huanXinConfig.getAppName()).concat("/token"),params, Map.class);
            int code = result.getStatusCodeValue();
            if (code == 200) {
                Map map = result.getBody();
                this.TOKEN = (String) map.get("access_token");
                this.TOKENTIME = Long.parseLong((String) map.get("expires_in")) * 1000;
                this.GRANTTOKENTIME = System.currentTimeMillis();
            } else {
                logger.error("无法获取环信TOKEN!code is {}",code);
                throw new RuntimeException("无法获取环信TOKEN!");
            }
            return this.TOKEN;
        }
    }

    @Override
    public RegisterResult register4HX(String username, String password, String nickname) throws IOException {
        MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
        params.add("username",username);
        params.add("password",password);
        params.add("nickname",nickname);
        ResponseEntity<String> result = this.restTemplate.postForEntity("http://a1.easemob.com/".concat(huanXinConfig.getOrgName()).concat("/").concat(huanXinConfig.getAppName()).concat("/token"),params, String.class);
        int code = result.getStatusCodeValue();
        if (code == 200) {
            String str = result.getBody();
            ObjectMapper mapper = new ObjectMapper();
            JsonNode node = mapper.readTree(str);
            JsonNode dest = node.findValue("entities");
            List<RegisterResult> rr = mapper.readValue(dest.asText(), mapper.getTypeFactory().constructCollectionType(List.class,RegisterResult.class));
            return rr.get(0);
        } else {
            logger.error("无法注册环信用户!code is {}",code);
            throw new RuntimeException("无法注册环信用户!");
        }
    }

    @Override
    public List<RegisterResult> mutilRegister4HX(List<RegisterVO> params) throws IOException {
        ResponseEntity<String> result = this.restTemplate.postForEntity("http://a1.easemob.com/{1}/{2}/users",params,String.class,huanXinConfig.getOrgName(),huanXinConfig.getAppName());
        int code = result.getStatusCodeValue();
        if (code == 200) {
            String str = result.getBody();
            ObjectMapper mapper = new ObjectMapper();
            JsonNode node = mapper.readTree(str);
            JsonNode dest = node.findValue("entities");
            return mapper.readValue(dest.asText(), mapper.getTypeFactory().constructCollectionType(List.class,RegisterResult.class));
        } else {
            logger.error("无法注册环信用户!code is {}",code);
            throw new RuntimeException("无法注册环信用户!");
        }
    }

    @Override
    public boolean removefromHX(String username) {
        ResponseEntity<Map> result =  this.restTemplate.exchange("http://a1.easemob.com/{1}/{2}/users/{3}", HttpMethod.DELETE,null,Map.class,huanXinConfig.getOrgName(),huanXinConfig.getAppName(),username);
        if (result.getStatusCodeValue() == 200) {
            return true;
        }
        return false;
    }


}
